/*
 * @Description: 参数验证管道
 * @Author: Haor
 * @Date: 2022-04-02 23:17:34
 * @LastEditTime: 2022-04-06 21:01:30
 * @LastEditors: Haor
 */

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'
import { validate } from 'class-validator'
import { plainToClass } from 'class-transformer'
import { HttpResult } from '@libs/http.result'
import { ParamsException } from "@exceptions";
import { Logger } from "@utils/log4";

@Injectable()
export class ValidationPipe implements PipeTransform {
	async transform(value: any, { metatype }: ArgumentMetadata): Promise<any> {
		if (!metatype || !this.toValidate(metatype)) {
			// 如果不是注入的数据且不需要验证，直接跳过处理
			return value
		}
		// 数据格式转换
		const object = plainToClass(metatype, value)
		// 调用验证
		const errors = await validate(object)
		// 如果错误长度大于0，证明出错，需要抛出400错误
		if (errors.length > 0) {
            const errorMessage = Object.values(errors[0].constraints)[0]; // 只需要取第一个错误信息并返回即可
            Logger.error(`Validation failed: ${errorMessage}`);
			throw new ParamsException(errorMessage)
		}
		return value
	}

	/**
	 * 验证方法
	 * @param {Any} metatype
	 * @return {Boolean}
	 */
	private toValidate(metatype: any): boolean {
		const types: any[] = [String, Boolean, Number, Array, Object]
		return !types.includes(metatype)
	}
}
